﻿// Copyright (c) 2014 Morten Bakkedal
// This code is published under the MIT License.

using System;
using System.Collections.Generic;
using System.Text;

namespace FuncLib.DualFunctions.Compilation
{
	public class IndexList : IEquatable<IndexList>
	{
		private List<int> offsets;
		private int hashCode;

		private IndexList()
		{
			offsets = new List<int>();
			hashCode = 23;
		}

		public IndexList(int[] offsets)
			: this()
		{
			foreach (int offset in offsets)
			{
				Add(offset);
			}
		}

		public IndexList(IndexList indexList, int offset)
		{
			throw new NotImplementedException();
		}

		private void Add(int offset)
		{
			offsets.Add(offset);
			unchecked
			{
				hashCode = hashCode * 31 + offset.GetHashCode();
			}
		}

		public string GenerateCode()
		{
			StringBuilder sb = new StringBuilder();
			sb.Append("new int[] { ");
			for (int i = 0; i < offsets.Count; i++)
			{
				if (i > 0)
				{
					sb.Append(", ");
				}
				sb.Append(offsets[i]);
			}
			sb.Append(" }");
			return sb.ToString();
		}

		public bool Equals(IndexList other)
		{
			// Follows Item 6 in Effective C# in first three tests.

			if (object.ReferenceEquals(other, null))
			{
				return false;
			}

			if (object.ReferenceEquals(this, other))
			{
				return true;
			}

			if (GetType() != other.GetType())
			{
				return false;
			}

			if (hashCode != other.hashCode)
			{
				// Can't be equal if they have different hash codes.
				return false;
			}

			if (offsets.Count != other.offsets.Count)
			{
				return false;
			}

			for (int i = 0; i < offsets.Count; i++)
			{
				if (offsets[i] != other.offsets[i])
				{
					return false;
				}
			}

			// No differences found.
			return true;
		}

		public override bool Equals(object other)
		{
			return Equals(other as IndexList);
		}

		public override int GetHashCode()
		{
			return hashCode;
		}

		public int Count
		{
			get
			{
				return offsets.Count;
			}
		}
	}
}
